<?php
require_once "DatabaseManager.php";
require_once "utils/Utils.php";
require_once "data/Booking.php";
require_once "UsersManager.php";

class BookingsManager extends DatabaseManager {
	
	// This function translates the SQL results into JSON
	private function getBookingsFromRows($queryResults) {
			$jsonResults = array();
			while ($row = mysql_fetch_array($queryResults)) {
				 $bookingJSON = array();
				 // Booking ID
				 $bookingJSON[JSON_Tags::BOOKING_ID] = $row['booking_id'];
				 // Booking Start Date
				 $bookingJSON[JSON_Tags::BOOKING_START_DATE] = $row['booking_start_date'];
				 // Booking End Date
				 $bookingJSON[JSON_Tags::BOOKING_END_DATE] = $row['booking_end_date'];
				 // Teacher
				 $teacherJSON = array();
				 // Teacher Id
				 $teacherJSON[JSON_Tags::TEACHER_ID] = $row['teacher_id'];
				 // Teacher First Name
				 $teacherJSON[JSON_Tags::TEACHER_FIRST_NAME] = $row['teacher_first_name'];
				 // Teacher Last Name
				 $teacherJSON[JSON_Tags::TEACHER_LAST_NAME] = $row['teacher_last_name'];
				 // Teacher Positon
				 $teacherJSON[JSON_Tags::TEACHER_POSITION] = $row['teacher_position'];
				 // Set Teacher
				 $bookingJSON[JSON_Tags::BOOKING_TEACHER] = $teacherJSON;
				 
                 // Course
                 $courseJSON = array();
                 // Course code
                 $courseJSON[JSON_Tags::COURSE_CODE] = $row['course_code'];
                 // Course name
                 $courseJSON[JSON_Tags::COURSE_NAME] = $row['course_name'];
                 // Faculty id
                 $courseJSON[JSON_Tags::FACULTY_ID] = $row['faculty_id'];
                 // Self URI
				 $courseJSON[JSON_Tags::SELF_URL] = PROTOCOL.$_SERVER['SERVER_NAME'].EntryPoints::API.EntryPoints::COURSES.'/'.$row['course_code'];
                 // Set Course
                 $bookingJSON[JSON_Tags::BOOKING_COURSE] = $courseJSON;
				 
				 
				  // Room
                 $roomJSON = array();
                 // Room Id
                 $roomJSON[JSON_Tags::ROOM_ID] = $row['room_id'];
                 // Room Name
                 $roomJSON[JSON_Tags::ROOM_NAME] = $row['room_name'];
                 // Booking Id
                 $roomJSON[JSON_Tags::BUILDING_ID] = $row['building_id'];
                 // Building Name
                 $roomJSON[JSON_Tags::BUILDING_NAME] = $row['building_name'];
                 // Self_URL
				 $roomJSON[JSON_Tags::SELF_URL] = PROTOCOL.$_SERVER['SERVER_NAME'].EntryPoints::API.EntryPoints::ROOMS.'/'.$row['room_id'];
                 // Set Course
                 $bookingJSON[JSON_Tags::BOOKING_ROOM] = $roomJSON;

                  // Type of Class
				 $type_of_classJSON = array();
				 // Type of Class Id
				 $type_of_classJSON[JSON_Tags::TYPE_OF_CLASS_ID] = $row['class_id']; 
				 // Type Of Class Name
				 $type_of_classJSON[JSON_Tags::TYPE_OF_CLASS_NAME] = $row['class_name'];
				 // Set Type of Class
				 $bookingJSON[JSON_Tags::BOOKING_TYPE_OF_CLASS] = $type_of_classJSON;
				 
				 // Study Groups
				 $bookingId = $bookingJSON[JSON_Tags::BOOKING_ID];
				 $queryString2 = "SELECT s.id as study_group_id, s.name as study_group_name FROM bookings_studygroups as bs INNER JOIN study_groups as s ON bs.studygroup_id = s.id WHERE bs.booking_id = $bookingId";
				 $queryResults2 = mysql_query($queryString2,$this->connection);
				 $numberOfRows2 = mysql_num_rows($queryResults2);
		 		 $studyGroups = array();
				 if ($numberOfRows2 > 0) {
					  while ($row2 = mysql_fetch_array($queryResults2)) {
						  $studyGroupJSON = array();
						  // Study group Id
						  $studyGroupJSON[JSON_Tags::STUDY_GROUP_ID] = $row2['study_group_id'];
						  // Study group Name
						  $studyGroupJSON[JSON_Tags::STUDY_GROUP_NAME] = $row2['study_group_name'];
						  
						  array_push($studyGroups, $studyGroupJSON);
					  }
				 }
				 // Set study groups
				 $bookingJSON[JSON_Tags::BOOKING_STUDY_GROUPS] = $studyGroups;
				 // Set Self URL
				 $bookingJSON[JSON_Tags::SELF_URL] =  PROTOCOL.$_SERVER['SERVER_NAME'].EntryPoints::API.EntryPoints::BOOKINGS.'/'.$row['booking_id'];
				 
				 array_push($jsonResults,$bookingJSON); 
			}
			return $jsonResults;
	}

	private function getBookingById($bookingId) {
		 $queryString = "SELECT b.id as booking_id, b.start_date as booking_start_date, b.end_date as booking_end_date, t.id as teacher_id, t.first_name as teacher_first_name, t.last_name as teacher_last_name, t.position as teacher_position, c.code as course_code, c.name as course_name, c.faculty_id as faculty_id, cl.id as class_id, r.id as room_id, r.name as room_name, bu.id as building_id, bu.name as building_name, cl.name as class_name FROM bookings as b INNER JOIN types_of_classes as cl ON b.type_of_class_id = cl.id INNER JOIN teachers_courses as tc ON tc.id = b.teacher_course_id INNER JOIN teachers as t ON tc.teacher_id = t.id INNER JOIN courses as c ON c.code = tc.course_code INNER JOIN rooms as r ON b.room_id = r.id INNER JOIN buildings as bu ON r.building_id = bu.id WHERE b.id = $bookingId ORDER BY b.start_date";
		 $queryResults = mysql_query($queryString, $this->connection);
		 $numberOfRows = mysql_num_rows($queryResults);
		 $jsonResults = array();
		 if ($numberOfRows > 0) {
			 // Booking was found
			 $jsonResults = $this->getBookingsFromRows($queryResults);
			 $this->response($this->toJSON($jsonResults[0]),StatusCodes::STATUS_CODE_SUCCESS);	
		 } else {
			 // No results found
			$jsonResults[MESSAGE] = Strings::NO_BOOKINGS_RESULTS_MESSAGE;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_NOT_FOUND); 
		 }
	}
	
	private function getBookingsForRoom($roomId, $date) {
		// Validate date
		if (validateDate($date)) {
		 $queryString = "SELECT b.id as booking_id, b.start_date as booking_start_date, b.end_date as booking_end_date, t.id as teacher_id, t.first_name as teacher_first_name, t.last_name as teacher_last_name, t.position as teacher_position, r.id as room_id, r.name as room_name, c.code as course_code, c.name as course_name, c.faculty_id as faculty_id, bu.id as building_id, bu.name as building_name, cl.id as class_id, cl.name as class_name FROM bookings as b INNER JOIN types_of_classes as cl ON b.type_of_class_id = cl.id INNER JOIN teachers_courses as tc ON tc.id = b.teacher_course_id INNER JOIN teachers as t ON tc.teacher_id = t.id INNER JOIN courses as c ON c.code = tc.course_code INNER JOIN rooms as r ON r.id = b.room_id INNER JOIN buildings as bu ON r.building_id = bu.id WHERE b.room_id = $roomId and DATE_FORMAT(b.start_date,'%Y-%m-%d') = '$date' ORDER BY b.start_date";
		 $queryResults = mysql_query($queryString, $this->connection);
		 $numberOfRows = mysql_num_rows($queryResults);
		 $jsonResults = array();
		 if ($numberOfRows > 0) {
			$jsonResults = $this->getBookingsFromRows($queryResults);
		  	// Send the response
		 	$this->response($this->toJSON($jsonResults),StatusCodes::STATUS_CODE_SUCCESS);	
		 } 
		 else {
			// No results found
			$this->response(null, StatusCodes::STATUS_CODE_NO_CONTENT);
			} 
		}
	   else {
			// Invalid Date	
		$jsonResults[MESSAGE] = Strings::INVALID_DATE;
		$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST); 	
	  }
}
   	
	private function getBookingsForCourse($courseCode) {
		 $courseCode = strtolower($courseCode);
		 $queryString = "SELECT b.id as booking_id, b.start_date as booking_start_date, b.end_date as booking_end_date, t.id as teacher_id, t.first_name as teacher_first_name, t.last_name as teacher_last_name, t.position as teacher_position, r.id as room_id, r.name as room_name, c.code as course_code, c.name as course_name, c.faculty_id as faculty_id, bu.id as building_id, bu.name as building_name, cl.id as class_id, cl.name as class_name FROM bookings as b INNER JOIN types_of_classes as cl ON b.type_of_class_id = cl.id INNER JOIN teachers_courses as tc ON tc.id = b.teacher_course_id INNER JOIN teachers as t ON tc.teacher_id = t.id INNER JOIN courses as c ON c.code = tc.course_code INNER JOIN rooms as r ON b.room_id = r.id INNER JOIN buildings as bu ON r.building_id = bu.id WHERE LOWER(tc.course_code) = '$courseCode' ORDER BY b.start_date";
		 $queryResults = mysql_query($queryString, $this->connection);
		 $numberOfRows = mysql_num_rows($queryResults);
		 $jsonResults = array();
		 if ($numberOfRows > 0) {
			$jsonResults = $this->getBookingsFromRows($queryResults);
		  	// Send the response
		 	$this->response($this->toJSON($jsonResults),StatusCodes::STATUS_CODE_SUCCESS);	
		} else {
			// No results found
			$jsonResults[MESSAGE] = Strings::NO_BOOKINGS_RESULTS_MESSAGE;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_NOT_FOUND); 	
		} 
	}
	
	private function checkUserPermissions($bookingId, $userInfo) {
			// Check if the teacher is allowed to delete the booking
			if ($userInfo->userType == UserType::SECRETARY) {
				//$queryString = "SELECT * FROM bookings as b where b.id = $bookingId";
				// Secretary Code. It is not the purpose of my application in this stage
				$jsonResults[MESSAGE] = Strings::SECRETARY_SUPPORT;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
			}
			else {
				$queryString = "SELECT * FROM bookings as b INNER JOIN teachers_courses as tc ON b.teacher_course_id = tc.id WHERE tc.teacher_id = $userInfo->userId AND b.id = $bookingId";
			}
		 	$queryResults = mysql_query($queryString, $this->connection);
		 	$numberOfRows = mysql_num_rows($queryResults);
			if ($numberOfRows > 0) {
				return true;	
			}
			return false;
	}
	
	private function deleteBooking($bookingId, $userInfo) {
		   if ($this->checkUserPermissions($bookingId, $userInfo)) {
               // Get Booking Start Date and Course Code
               $queryString = "SELECT b.start_date, tc.course_code FROM (SELECT * FROM bookings WHERE id = $bookingId) as b INNER JOIN teachers_courses as tc ON b.teacher_course_id = tc.id";
               
               $queryResults = mysql_query($queryString, $this->connection);
               $numberOfRows = mysql_num_rows($queryResults);
               if ($numberOfRows > 0) {
                   $row = mysql_fetch_array($queryResults);
                   $courseCode = $row['course_code'];
                   $startDate = $row['start_date'];
               }
               
				// User is either a secretary or has permissions to modify the booking
				$queryString = "DELETE FROM bookings WHERE id = $bookingId";
		 		$success= mysql_query($queryString, $this->connection);
				if ($success) {
                    // Language
                    $headers =  apache_request_headers();
                    if(isset($headers['Accept-Language'])) {
                       $lng = $headers['Accept-Language'];
                    } else {
                       $lng = 'eng';
                    }
                    // Notify Devices starting a new process
                    $command = "/Applications/MAMP/bin/php/php5.4.10/bin/php managers/NotificationsScript.php $courseCode '$startDate' d '$lng' > /dev/null &";
                    exec($command);
                    
					$this->response("",StatusCodes::STATUS_CODE_NO_CONTENT);
				} else {	
					$jsonResults[MESSAGE] = Strings::DATA_BASE_ERROR;
					$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_SERVER_ERROR); 
				}
		   } else {
			    // No permissions or invalid booking id
				$jsonResults[MESSAGE] = Strings::NO_PERMISSIONS_FOR_BOOKING;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);   
		   }
				
	}
	
	private function updateBooking($booking, $userInfo) {
		if ($this->checkUserPermissions($booking->bookingId, $userInfo)) {
				// Update bookings table
				$queryString = "UPDATE bookings SET start_date = '$booking->bookingStartDate', end_date = '$booking->bookingEndDate', room_id = $booking->bookingRoomId, type_of_class_id = $booking->bookingTypeOfClass WHERE id = $booking->bookingId";
				$success= mysql_query($queryString, $this->connection);
				if (!$success) {
					$jsonResults[MESSAGE] = Strings::DATA_BASE_ERROR;
					$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_SERVER_ERROR); 	
				}
				// Update booking_studygroups table
				$queryString = "DELETE FROM bookings_studygroups WHERE booking_id = $booking->bookingId";
				$success= mysql_query($queryString, $this->connection);
				if (!$success) {
					$jsonResults[MESSAGE] = Strings::DATA_BASE_ERROR;
					$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_SERVER_ERROR); 	
				}
				foreach($booking->bookingStudyGroups as $studyGroup) {
					$queryString = "INSERT INTO bookings_studygroups (booking_id, studygroup_id) VALUES ($booking->bookingId, $studyGroup)";
					$success= mysql_query($queryString, $this->connection);
					if (!$success) {
						$jsonResults[MESSAGE] = Strings::DATA_BASE_ERROR;
						$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_SERVER_ERROR); 	
					}
				}
               // Language
               $headers =  apache_request_headers();
               if(isset($headers['Accept-Language'])) {
                  $lng = $headers['Accept-Language'];
                } else {
                  $lng = 'eng';
                }
                // Notify Devices starting a new process
                $command = "/Applications/MAMP/bin/php/php5.4.10/bin/php managers/NotificationsScript.php $booking->bookingCourseCode '$booking->bookingStartDate' u '$lng' > /dev/null &";
                exec($command);
            
				// If we got to this step everything worked well so we can send a success code back together with the updated booking
				$this->getBookingById($booking->bookingId);				
		}
	  else {
			// No permissions or invalid booking id
			$jsonResults[MESSAGE] = Strings::NO_PERMISSIONS_FOR_BOOKING;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
	    }
    }
	
	private function addBooking($booking) {
		$queryString = "INSERT INTO bookings(start_date, end_date, teacher_course_id, room_id, type_of_class_id) VALUES ('$booking->bookingStartDate', '$booking->bookingEndDate', $booking->bookingTeacherCourseId, $booking->bookingRoomId, $booking->bookingTypeOfClass)";
		$success= mysql_query($queryString, $this->connection);
		if (!$success) {
				$jsonResults[MESSAGE] = Strings::DATA_BASE_ERROR;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_SERVER_ERROR); 	
		}
		// Update booking_studygroups table
		$booking->bookingId = mysql_insert_id();
		foreach($booking->bookingStudyGroups as $studyGroup) {
			$queryString = "INSERT INTO bookings_studygroups (booking_id, studygroup_id) VALUES ($booking->bookingId, $studyGroup)";
			$success= mysql_query($queryString, $this->connection);
			if (!$success) {
					$jsonResults[MESSAGE] = Strings::DATA_BASE_ERROR;
					$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_SERVER_ERROR); 	
			}
		}
       // Language
        $headers =  apache_request_headers();
        if(isset($headers['Accept-Language'])) {
           $lng = $headers['Accept-Language'];
        } else {
           $lng = 'eng';
        }
        // Notify Devices starting a new process
        $command = "/Applications/MAMP/bin/php/php5.4.10/bin/php managers/NotificationsScript.php $booking->bookingCourseCode '$booking->bookingStartDate' a '$lng'> /dev/null &";
        exec($command);
        
        $this->getBookingById($booking->bookingId);
	}
   
   // $allTags flag indicates if we need to parse all the tags. If we only update a booking, we won't parse all the flags
   private function createBookingFromJSON ($jsonData, $allTags) {
		$booking = new Booking();
		// Check Start Date
		if (isset($jsonData[JSON_Tags::BOOKING_START_DATE])) {
			if (validateDateTime($jsonData[JSON_Tags::BOOKING_START_DATE])) {
				$booking->bookingStartDate = $jsonData[JSON_Tags::BOOKING_START_DATE];	
			} else {
				$jsonResults[MESSAGE] = Strings::BOOKING_START_DATE_INVALID;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
			}
		} else {
				$jsonResults[MESSAGE] = Strings::BOOKING_START_DATE;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
		}
		// Check End Date
		if (isset($jsonData[JSON_Tags::BOOKING_END_DATE])) {
			if (validateDateTime($jsonData[JSON_Tags::BOOKING_END_DATE])) {
				$booking->bookingEndDate = $jsonData[JSON_Tags::BOOKING_END_DATE];	
			} else {
				$jsonResults[MESSAGE] = Strings::BOOKING_END_DATE_INVALID;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
			}
		} else {
				$jsonResults[MESSAGE] = Strings::BOOKING_END_DATE;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
		}
		if ($allTags) {
			// Check Teacher Id
			if (isset($jsonData[JSON_Tags::TEACHER_ID])) {
				if (is_numeric($jsonData[JSON_Tags::TEACHER_ID])) {
					$booking->bookingTeacherId = $jsonData[JSON_Tags::TEACHER_ID];
				} else {
					$jsonResults[MESSAGE] = Strings::BOOKING_TEACHER_ID_INVALID;
					$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
				}
			} else {
				$jsonResults[MESSAGE] = Strings::BOOKING_TEACHER_ID;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
			}
			// Check Course Code
			if (isset($jsonData[JSON_Tags::COURSE_CODE])) {
				$booking->bookingCourseCode = strtolower(addslashes($jsonData[JSON_Tags::COURSE_CODE]));
			} else {
				$jsonResults[MESSAGE] = Strings::BOOKING_COURSE_CODE;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
			}
		}
		// Check Room Id
		if (isset($jsonData[JSON_Tags::ROOM_ID])) {
			if (is_numeric($jsonData[JSON_Tags::ROOM_ID])) {
				$booking->bookingRoomId = $jsonData[JSON_Tags::ROOM_ID];
			}	
			else {
				$jsonResults[MESSAGE] = Strings::BOOKING_ROOM_ID_INVALID;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
			}
		} else {
			$jsonResults[MESSAGE] = Strings::BOOKING_ROOM_ID;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
		}
		// Check Type of Class
		if (isset($jsonData[JSON_Tags::TYPE_OF_CLASS_ID])) {
			if (is_numeric($jsonData[JSON_Tags::TYPE_OF_CLASS_ID])) {
				$booking->bookingTypeOfClass = $jsonData[JSON_Tags::TYPE_OF_CLASS_ID];
			}	
			else {
				$jsonResults[MESSAGE] = Strings::BOOKING_TYPE_OF_CLASS_ID_INVALID;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
			}
		} else {
			$jsonResults[MESSAGE] = Strings::BOOKING_TYPE_OF_CLASS_ID;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
		}
		// Check Study Groups
		if (isset($jsonData[JSON_Tags::BOOKING_STUDY_GROUPS])) {
			$studyGroups = $jsonData[JSON_Tags::BOOKING_STUDY_GROUPS];
			if (is_array($studyGroups)) {
				$booking->bookingStudyGroups = array();
				foreach($studyGroups as $studyGroup) {
					if (isset($studyGroup[JSON_Tags::STUDY_GROUP_ID])) {
						if (is_numeric($studyGroup[JSON_Tags::STUDY_GROUP_ID])) 
							array_push($booking->bookingStudyGroups, $studyGroup[JSON_Tags::STUDY_GROUP_ID]);
					}
					else {
						$jsonResults[MESSAGE] = Strings::BOOKING_STUDY_GROUPS_INVALID;
						$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
					}
				}
			} else {
				$jsonResults[MESSAGE] = Strings::BOOKING_STUDY_GROUPS_INVALID;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
			}
		} else {
			$jsonResults[MESSAGE] = Strings::BOOKING_STUDY_GROUPS;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
		}
		// Check if there are no extra tags
		if ((count($jsonData) != 7 )&&(!$allTags && count($jsonData) != 5)) {
			$jsonResults[MESSAGE] = Strings::INVALID_BOOKING_JSON_FORMAT;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
		}
		return $booking;
   }
   
   // $newBooking is a flag that indicates if we need to validate all the fields
   private function validateBooking(Booking $booking, $newBooking) {
	   // First check if both starting date and ending date are "later" than current time
	   $startDate = new DateTime($booking->bookingStartDate);
	   $endDate = new DateTime ($booking->bookingEndDate);
	   $now = new DateTime();
	   
	   if (!$newBooking) {
		   // Validate booking id
		   $queryString = "SELECT course_code FROM (SELECT teacher_course_id  from bookings WHERE id = $booking->bookingId) AS booking INNER JOIN teachers_courses ON booking.teacher_course_id = teachers_courses.id";
		   $queryResults = mysql_query($queryString, $this->connection);
		   $numberOfRows = mysql_num_rows($queryResults); 
		   if ($numberOfRows < 1) {
				// Invalid teacher - course association
				$jsonResults[MESSAGE] = Strings::BOOKING_INVALID_BOOKING_ID;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
			} else {
				// Set bookingTeacherCourseId
				$row = mysql_fetch_array($queryResults);
				$booking->bookingCourseCode = $row['course_code'];	
			}
	   }
	   if ($startDate < $now || $endDate < $now) {
			$jsonResults[MESSAGE] = Strings::BOOKING_DATES_IN_THE_PAST;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);   
	   }
	   // $startDate and $endDate must be in the same date
	   if ($startDate->format("Y-m-d") != $endDate->format("Y-m-d")) {
		   	$jsonResults[MESSAGE] = Strings::BOOKING_DATES_SAME_DAY;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);  
	   }
	   // $starDate should be earlier tahn $endDate
	   if ($startDate > $endDate) {
		   	$jsonResults[MESSAGE] = Strings::BOOKING_DATES_EARLIER;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST); 
	   }
	   // $The booking should last at least 60 minutes
	   if( ($endDate->getTimestamp() - $startDate->getTimestamp()) / 60 < 60) {
		   	$jsonResults[MESSAGE] = Strings::BOOKING_DATES_60_MINUTES;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST); 
	   }
	   // Check if the creator is assigned to the selected course
	   if ($newBooking) {
			$queryString = "SELECT id from teachers_courses WHERE teacher_id = $booking->bookingTeacherId AND LOWER(course_code) = '$booking->bookingCourseCode'";
			$queryResults = mysql_query($queryString, $this->connection);
			$numberOfRows = mysql_num_rows($queryResults); 
			if ($numberOfRows < 1) {
				// Invalid teacher - course association
				$jsonResults[MESSAGE] = Strings::BOOKING_INVALID_TEACHER_COURSE;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
			} else {
				// Set bookingTeacherCourseId
				$row = mysql_fetch_array($queryResults);
				$booking->bookingTeacherCourseId = $row['id'];	
			}
	   } 
	   // Check if the room is available for the course's faculty
	   $queryString = "SELECT * FROM rooms_faculties as rf INNER JOIN courses as c ON rf.faculty_id = c.faculty_id WHERE LOWER(c.code) = '$booking->bookingCourseCode' AND rf.room_id = $booking->bookingRoomId";
	   $queryResults = mysql_query($queryString, $this->connection);
	   $numberOfRows = mysql_num_rows($queryResults); 
	   if ($numberOfRows < 1) {
			// The room is not available for the selected course
			$jsonResults[MESSAGE] = Strings::BOOKING_INVALID_ROOM_FACULTY;
			$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
	   }
	   // Check if the room is free in the selected interval
	   $queryString = "SELECT id FROM bookings WHERE room_id = $booking->bookingRoomId AND (('$booking->bookingStartDate' > start_date AND '$booking->bookingStartDate' < end_date) OR ('$booking->bookingEndDate' > start_date AND '$booking->bookingEndDate' < end_date) OR ('$booking->bookingEndDate' > end_date AND '$booking->bookingStartDate' < start_date))";
	   $queryResults = mysql_query($queryString, $this->connection);
	   $numberOfRows = mysql_num_rows($queryResults); 
	   if ($numberOfRows > 0) {
		    if ($newBooking) {
				// The room is already booked for the selected time interval
				$jsonResults[MESSAGE] = Strings::BOOKING_ROOM_ALREADY_BOOKED;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);		
			} else {
			    // Check if the booking that has the same time interval is the booking that we are trying to update
				$row = mysql_fetch_array($queryResults);
				$bookingId = $row['id'];
				if ($bookingId != $booking->bookingId) {
					//The room is already booked for the selected time interval
					$jsonResults[MESSAGE] = Strings::BOOKING_ROOM_ALREADY_BOOKED;
					$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
				}
			}
	   }
	   // Check if course has the selected type of class. All classes can book EXAMEN, CONSULTATII, RECUPERARE
	   if ($booking->bookingTypeOfClass != TypeOfClass::EXAMEN && $booking->bookingTypeOfClass != TypeOfClass::RECUPERARE && $booking->bookingTypeOfClass != TypeOfClass::CONSULTATII && $booking->bookingTypeOfClass != TypeOfClass::OTHER) {
		   $queryString = "SELECT * FROM courses_typesofclasses WHERE LOWER(course_code) = '$booking->bookingCourseCode' AND type_of_class_id = $booking->bookingTypeOfClass";
		   $queryResults = mysql_query($queryString, $this->connection);
		   $numberOfRows = mysql_num_rows($queryResults); 
		   if ($numberOfRows < 1) {
				// The room is already booked for the selected time interval
				$jsonResults[MESSAGE] = Strings::BOOKING_COURSE_TYPE_OF_CLASS;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
		   }
	   }
	   
	   // Booking is valid
	   return $booking;
	   
	   
   }
   public function processApi() {
	    // Check authorization token
		$userManager = new UsersManager();
		$userInfo = $userManager->getUserInfoForAuthorization();
        $this->_request = file_get_contents("php://input");
		$METHOD = $this->get_request_method();
		switch($METHOD) {
			case "GET": {
				// Check if Room Id and Date Are set
				if (isset($_GET['roomId']) && isset($_GET['date'])) {
					$roomId = addslashes($_GET['roomId']);
					$date = addslashes($_GET['date']);
					$this->getBookingsForRoom($roomId, $date);
				} else if (isset($_GET['courseCode'])) {
					// Check if couurseCode is set
					$courseCode = addslashes($_GET['courseCode']);
					$this->getBookingsForCourse($courseCode);
				} else if (isset ($_GET['bookingId'])) {
					// Check if booking id is set
					$bookingId = addslashes($_GET['bookingId']);
					$this->getBookingById($bookingId);
				} else {
					// Bad request
					$jsonResults[MESSAGE] = Strings::BAD_REQUEST;
					$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);  
				}
				break;
			}
		    case "POST": {
				if ($userInfo->userType == UserType::TEACHER || $userInfo->userType == UserType::SECRETARY) {
					// Create a new booking
					$postContent = json_decode($this->_request, true);
					if ($postContent) {
						$booking = $this->createBookingFromJSON($postContent, true);
						$booking = $this->validateBooking($booking, true);
						$this->addBooking($booking);		
					} else {
						// Bad JSON
						$jsonResults[MESSAGE] = Strings::BAD_REQUEST;
						$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST); 
					}
				} else {
					// Forbidden	
					$jsonResults[MESSAGE] = Strings::USER_FORBIDDEN;
					$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_FORBIDDEN);
				}
			break;
		  }
		  case "PUT" : {
			  // Update an existing booking
			if ($userInfo->userType == UserType::TEACHER || $userInfo->userType == UserType::SECRETARY) {
				parse_str($_SERVER['QUERY_STRING'], $queryStringParsed);
				if (isset($queryStringParsed['bookingId'])) {
						$bookingId = addslashes($queryStringParsed['bookingId']);
				} else {
						$jsonResults[MESSAGE] = Strings::BAD_REQUEST;
						$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
				}
				$postContent = json_decode($this->_request, true);
				if ($postContent) {
						$booking = $this->createBookingFromJSON($postContent, false);
						$booking->bookingId = $bookingId;
						$booking = $this->validateBooking($booking, false);
						$this->updateBooking($booking, $userInfo);	
				} else {
					// Bad JSON
					$jsonResults[MESSAGE] =  Strings::BAD_REQUEST;
					$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST); 
				}
			} else {
					// Forbidden	
					$jsonResults[MESSAGE] = Strings::USER_FORBIDDEN;
					$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_FORBIDDEN);
				}
			break;  
		  }
		  case "DELETE" : {
			  // Delete a booking
			  if ($userInfo->userType == UserType::TEACHER || $userInfo->userType == UserType::SECRETARY) {
			  		parse_str($_SERVER['QUERY_STRING'], $queryStringParsed);
					if (isset($queryStringParsed['bookingId'])) {
						$bookingId = addslashes($queryStringParsed['bookingId']);
						$this->deleteBooking($bookingId,$userInfo);
					} else {
						$jsonResults[MESSAGE] = Strings::BAD_REQUEST;
						$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
					}
			  }
			  else {
					// Forbidden	
					$jsonResults[MESSAGE] = Strings::USER_FORBIDDEN;
					$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_FORBIDDEN);
			}
			  break;
		  }
		  default : {
			  	// Not supported method	
				$jsonResults[MESSAGE] = Strings::HTTP_METHOD_NOT_SUPPORTED;
				$this->response($this->toJSON($jsonResults), StatusCodes::STATUS_CODE_BAD_REQUEST);
		  }
	}
   }
}
?>